#include <bits/stdc++.h>
using namespace std;

/*
2918. 数组的最小相等和
已解答
中等
相关标签
相关企业
提示
给你两个由正整数和 0 组成的数组 nums1 和 nums2 。

你必须将两个数组中的 所有 0 替换为 严格 正整数，并且满足两个数组中所有元素的和 相等 。

返回 最小 相等和 ，如果无法使两数组相等，则返回 -1 。

 

示例 1：

输入：nums1 = [3,2,0,1,0], nums2 = [6,5,0]
输出：12
解释：可以按下述方式替换数组中的 0 ：
- 用 2 和 4 替换 nums1 中的两个 0 。得到 nums1 = [3,2,2,1,4] 。
- 用 1 替换 nums2 中的一个 0 。得到 nums2 = [6,5,1] 。
两个数组的元素和相等，都等于 12 。可以证明这是可以获得的最小相等和。
示例 2：

输入：nums1 = [2,0,2,0], nums2 = [1,4]
输出：-1
解释：无法使两个数组的和相等。
 

提示：

1 <= nums1.length, nums2.length <= 105
0 <= nums1[i], nums2[i] <= 106
*/

// 法一
#include <vector>
using namespace std;

class Solution {
public:
    /**
     * @brief 计算两个数组的最小相等和
     * 
     * 将两个数组中的所有0替换为严格正整数，使得两个数组的和相等，
     * 并且这个和尽可能小。如果无法满足条件，则返回-1。
     * 
     * @param nums1 第一个数组，包含正整数和0
     * @param nums2 第二个数组，包含正整数和0
     * @return long long 最小相等和，无法满足时返回-1
     */
    long long minSum(vector<int>& nums1, vector<int>& nums2) {
        long long sum1 = 0; // nums1的元素和（0替换为1）
        long long sum2 = 0; // nums2的元素和（0替换为1）
        int count1 = 0;     // nums1中0的个数
        int count2 = 0;     // nums2中0的个数

        // 计算nums1的和(sum1)和0的个数(count1)
        for (int num : nums1) {
            if (num == 0) {
                count1++;    // 统计0的个数
                sum1 += 1;   // 0替换为最小的正整数1
            } else {
                sum1 += num; // 非零元素直接累加
            }
        }

        // 计算nums2的和(sum2)和0的个数(count2)
        for (int num : nums2) {
            if (num == 0) {
                count2++;    // 统计0的个数
                sum2 += 1;   // 0替换为最小的正整数1
            } else {
                sum2 += num; // 非零元素直接累加
            }
        }

        // 情况1：两个数组的和已经相等
        if (sum1 == sum2) {
            return sum1;
        } 
        // 情况2：nums1的和小于nums2的和
        else if (sum1 < sum2) {
            // 如果nums1中没有0，无法增加sum1，返回-1
            if (count1 == 0) {
                return -1;
            } 
            // 否则可以通过增加nums1中的0来使sum1等于sum2
            else {
                return sum2;
            }
        } 
        // 情况3：nums1的和大于nums2的和
        else {
            // 如果nums2中没有0，无法增加sum2，返回-1
            if (count2 == 0) {
                return -1;
            } 
            // 否则可以通过增加nums2中的0来使sum2等于sum1
            else {
                return sum1;
            }
        }
    }
};

// 法二
class Solution {
public:
    long long minSum(vector<int>& nums1, vector<int>& nums2) {
        // 初始化两个数组的和（sum1和sum2）以及0的个数（zero1和zero2）
        long long sum1 = 0, sum2 = 0;
        long long zero1 = 0, zero2 = 0;

        // 计算nums1的和（sum1）以及其中0的个数（zero1）
        for (int i : nums1) {
            sum1 += i;  // 累加当前元素到sum1
            if (i == 0) {
                sum1++;   // 如果当前元素是0，替换为1（最小正整数），所以sum1加1
                zero1++;  // 统计nums1中0的个数
            }
        }

        // 计算nums2的和（sum2）以及其中0的个数（zero2）
        for (int i : nums2) {
            sum2 += i;  // 累加当前元素到sum2
            if (i == 0) {
                sum2++;   // 如果当前元素是0，替换为1（最小正整数），所以sum2加1
                zero2++;  // 统计nums2中0的个数
            }
        }

        // 检查是否存在无法使两数组和相等的情况：
        // 1. 如果nums1没有0（zero1 == 0）且nums2的和大于nums1的和（sum2 > sum1）
        // 2. 或者nums2没有0（zero2 == 0）且nums1的和大于nums2的和（sum1 > sum2）
        // 满足以上任意一种情况，则无法通过替换0来使两数组和相等，返回-1
        if ((!zero1 && sum2 > sum1) || (!zero2 && sum1 > sum2)) {
            return -1;
        }

        // 如果可以通过替换0来使两数组和相等，则返回较大的和（max(sum1, sum2)）
        // 因为较小的和可以通过增加其中的0来匹配较大的和
        return max(sum1, sum2);
    }
};
